package com.pig4cloud.pigx.common.customize.utils;

import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author gong_da_kai
 * @version 1.0.0
 * @since 2021/11/20 11:07 上午
 */
public class ReflectUtil {
	/**
	 * get
	 */
	public static final String GET = "get";
	/**
	 * set
	 */
	public static final String SET = "set";

	/**
	 * 循环向上转型, 获取fieldName对应的Getter
	 * 如向上转型到Object仍无法找到, 返回null
	 *
	 * @param obj       对象
	 * @param fieldName 属性名
	 * @author gong_da_kai
	 * @since 2021/11/20
	 */
	public static Method getGetter(final Object obj, final String fieldName) {
		// 为空不报错。直接返回 null
		if (obj == null) {
			return null;
		}

		if (StringUtils.isEmpty(fieldName)) {
			throw new RuntimeException("fieldName can't be blank");
		}
		for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
			try {
				return superClass.getDeclaredMethod(getGetterStr(fieldName));
			} catch (NoSuchMethodException ignored) {
			}
		}

		return null;
	}

	/**
	 * 循环向上转型, 获取fieldName对应的Setter
	 * 如向上转型到Object仍无法找到, 返回null
	 *
	 * @param obj       对象
	 * @param fieldName 属性名
	 * @param filedType 属性类型
	 * @author gong_da_kai
	 * @since 2021/11/20
	 */
	public static Method getSetter(final Object obj, final String fieldName, final Class<?> filedType) {
		// 为空不报错。直接返回 null
		if (obj == null) {
			return null;
		}

		if (StringUtils.isEmpty(fieldName)) {
			throw new RuntimeException("fieldName can't be blank");
		}
		for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
			try {
				return superClass.getDeclaredMethod(getSetterStr(fieldName), filedType);
			} catch (NoSuchMethodException ignored) {
			}
		}

		return null;
	}

	/**
	 * 根据属性名获得getter
	 *
	 * @param fieldName 属性名
	 * @return java.lang.String
	 * @author gong_da_kai
	 * @since 2021/11/20
	 */
	public static String getGetterStr(final String fieldName) {
		return ReflectUtil.GET + firstLetter2Uppercase(fieldName);
	}

	/**
	 * 根据属性名获得setter
	 *
	 * @param fieldName 属性名
	 * @return java.lang.String
	 * @author gong_da_kai
	 * @since 2021/11/20
	 */
	public static String getSetterStr(final String fieldName) {
		return ReflectUtil.SET + firstLetter2Uppercase(fieldName);
	}

	/**
	 * 设置字符串的第一个字母为大写
	 *
	 * @param str 字符串
	 * @return java.lang.String
	 * @author gong_da_kai
	 * @since 2021/11/20
	 */
	public static String firstLetter2Uppercase(String str) {
		if (StringUtils.isEmpty(str)) {
			return str;
		}

		String firstLetter = String.valueOf(str.charAt(0));

		return str.replaceFirst(firstLetter, firstLetter.toUpperCase());
	}

	/**
	 * 获取类及其所有父类（不含Object）的属性
	 *
	 * @param type 类
	 * @return java.util.List<java.lang.reflect.Field>
	 * @author gong_da_kai
	 * @since 2021/12/22
	 */
	public static List<Field> getFiledAsList(Class<?> type) {
		List<Field> fieldList = new ArrayList<>();
		for (; !Object.class.getName().equals(type.getName()); type = type.getSuperclass()) {
			fieldList.addAll(Arrays.asList(type.getDeclaredFields()));
		}

		return fieldList;
	}
}
